﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.SharePoint;

namespace FindMetadata
{
    class Program
    {
        /// <summary>
        /// Main execution of the app.  Configuring usage stats logging.
        /// </summary>
        /// <param name="args"></param>
        [System.STAThreadAttribute()]
        [PreEmptive.Attributes.Setup(CustomEndpoint = "so-s.info/PreEmptive.Web.Services.Messaging/MessagingServiceV2.asmx")]
        [PreEmptive.Attributes.Teardown()]
        [PreEmptive.Attributes.Feature("FindMetadata")]
        static void Main(string[] args)
        {
            if (args.Count() == 0)
            {
                PrintUsage();
            }
            else
            {
                try
                {
                    //Move all command line arguments to a hash table.
                    System.Collections.Hashtable tbl = new System.Collections.Hashtable();
                    for (int i = 0; i < (args.Count() - 1); i += 2)
                    {
                        tbl.Add(args[i].ToLower(), args[i + 1]);
                    }
                    //Check if the required arguments were supplied
                    if (!tbl.ContainsKey("-url"))
                    {
                        PrintUsage();
                    }
                    else
                    {
                        StartProcessing();
                        bool blnFound = false;
                        //Create the log file
                        System.IO.StreamWriter sw = new System.IO.StreamWriter(ConvertArgsToLogFile(tbl["-url"].ToString()));
                        Console.ForegroundColor = ConsoleColor.Green;
                        Log("Identifying metadata for " + tbl["-url"].ToString(), sw);
                        Console.ForegroundColor = ConsoleColor.White;
                        //Get a site collection reference.
                        using (SPSite sps = new SPSite(tbl["-url"].ToString()))
                        {
                            //Process all sub webs in the site collection.
                            foreach (SPWeb spw in sps.AllWebs)
                            {
                                Log("Site: " + spw.Url, sw);
                                //Process all lists in each sub web.
                                foreach (SPList spl in spw.Lists)
                                {
                                    Log("  List: " + spl.Title + " - Type [" + spl.BaseTemplate.ToString() + "] containing " + spl.Folders.Count + " folders and " + spl.Items.Count + " files.", sw);
                                    //Process all fields in each list.
                                    foreach (SPField fld in spl.Fields)
                                    {
                                        //Check if the fields are user added fields.
                                        if ((fld.CanBeDeleted) && (fld.SourceId.ToString().ToLower().Substring(0, 7) != "http://") && (fld.Title.ToLower() != "merge") && (fld.Title.ToLower() != "relink"))
                                        {
                                            if (!blnFound)
                                            {
                                                blnFound = true;
                                                Log("    Potential custom fields:", sw);
                                            }
                                            Log("      " + fld.Title, sw);
                                        }
                                    }
                                    if (blnFound)
                                    {
                                        blnFound = false;
                                    }
                                    else
                                    {
                                        Log("    No custom fields.", sw);
                                    }
                                }
                            }
                        }
                        //Flush the log file.
                        sw.Flush();
                        StopProcessing();
                    }
                }
                catch (Exception ex)
                {
                    //Handle errors.
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine(ex.Message);
                    StopProcessing();
                }
            }
        }

        /// <summary>
        /// Usage display on the console.
        /// </summary>
        static void PrintUsage()
        {
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(@"Command line error.");
            Console.WriteLine(" ");
            Console.WriteLine("Usage:");
            Console.WriteLine("  " + Environment.GetCommandLineArgs()[0] + " -url <URL>");
            Console.WriteLine(@"    -url <URL> - URL of the target site collection e.g. http://www.crayveon.com/sites/Quix");
            Console.WriteLine(@" ");
            Console.WriteLine("    Example usage would be:");
            Console.WriteLine(@"    " + Environment.GetCommandLineArgs()[0] + " -url http://crayveon.com/sites/Quix");
        }

        /// <summary>
        /// Used to log to both screen and the log file.
        /// </summary>
        /// <param name="s">String to log.</param>
        /// <param name="sw">Log file to write to.</param>
        static void Log(string s, System.IO.StreamWriter sw)
        {
            Console.WriteLine(s);
            sw.WriteLine(s);
        }

        /// <summary>
        /// Create the log file name.
        /// </summary>
        /// <param name="arg">String to use in the creation of the log file name.</param>
        /// <returns></returns>
        static string ConvertArgsToLogFile(string arg)
        {
            return arg.Replace("http://", "").Replace(".", "-").Replace("/", "_").Replace(" ", "") + ".log";
        }

        /// <summary>
        /// Start the processing timer.
        /// </summary>
        [PreEmptive.Attributes.Feature("FindMetadata", EventType = PreEmptive.Attributes.FeatureEventTypes.Start)]
        static void StartProcessing()
        {
        }

        /// <summary>
        /// Stop the processing timer.
        /// </summary>
        [PreEmptive.Attributes.Feature("FindMetadata", EventType = PreEmptive.Attributes.FeatureEventTypes.Stop)]
        static void StopProcessing()
        {
        }
    }
}
